<?php

namespace App\Kuafu\Shop\Service;

use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Shop\Enum\CodeEnum;
use App\Kuafu\Shop\Enum\ShopRecordsEnum;
use App\Kuafu\Shop\Model\GuanyuanSyncShopListModel;
use App\Kuafu\Shop\Model\GyDailyDeliveryReportCHModel;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Model\ShopRecordsModel;
use App\Kuafu\Shop\Model\ShopStaffRecordModel;
use App\Kuafu\User\Model\User;
use App\Remote\Tiger\Common\CommonRemote;
use Carbon\Carbon;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Cache;

class ShopRecordService extends BaseService
{
    //门店备案

    public static function getList(
        $pageSize,
        $pageNum,
        $shopIds = [],
        $dimCode = '',
        $areaCode = 0,
        $status = null,
        $inShopStaffCount = 0,
        $recordStatus = 0,
        $councilorId = 0,
        $orderBy = [],
        $export = false,
        $activityDays = 0
    ) {
        //战区
        $formatDistrictList = [];
        try {
            $warZoneDistrictList = CommonRemote::getWarZoneDistrictList();
            foreach ($warZoneDistrictList as $item) {
                foreach ($item['provinceList'] ?? [] as $_item) {
                    $provinceCode                                 = $_item['provinceCode'];
                    $formatDistrictList[$provinceCode]            = $_item;
                    $formatDistrictList[$provinceCode]['warZone'] = $item['name'];
                }
            }
        } catch (\Exception $exception) {
        }

        // 更新门店日活操作  只支持单一活跃值 如果要支持多个 需要再开发
        if ($activityDays) {
            $cacheKey = 'shop_records_activity_days:' . Carbon::now()->toDateString() . ':' . $activityDays;
            if (!Cache::has($cacheKey)) {
                Cache::remember($cacheKey, Carbon::now()->endOfDay()->timestamp - time(), function () use ($activityDays) {
                    ShopRecordService::updateShopActivity($activityDays);
                    return true;
                });
            }
        }

        $fields = [
            'shop.shopCode',
            'shop.name',
            'shop.addressPrefix',
            'shop.province',
            'shop.councilorId',
            'shop.status',
            (new ShopRecordsModel())->getTable() . '.*'
        ];

        $query = ShopRecordsModel::query()
                                    ->leftJoin(
                                        (new Shop())->getTable() . ' as shop',
                                        (new ShopRecordsModel())->getTable() . '.shopId', '=', 'shop.id'
                                    )
                                    ->leftJoin(
                                        (new GuanyuanSyncShopListModel())->getTable() . " as gShop",
                                        (new ShopRecordsModel())->getTable() . '.shopCode', '=', 'gShop.code'
                                    )
                                    ->when($shopIds, function ($query) use ($shopIds) {
                                        $query->whereIn((new ShopRecordsModel())->getTable().'.shopId', $shopIds);
                                    })
                                    ->when($activityDays, function ($query) use ($activityDays) {
                                        $query->where('activityDays', $activityDays);
                                    })
                                    ->when($dimCode, function ($query) use ($dimCode) {
                                        if (is_numeric($dimCode)) {
                                            $query->where('shop.shopCode', $dimCode);
                                        } elseif (is_string($dimCode)) {
                                            $query->where('shop.name', 'like', '%' . $dimCode . '%');
                                        }
                                    })
                                    ->when($areaCode, function ($query) use ($areaCode) {
                                        $query->orWhere('shop.province', $areaCode)
                                              ->orWhere('shop.city', $areaCode)
                                              ->orWhere('shop.district', $areaCode);
                                    })
                                    ->when(isset($status) && $status !== '', function ($query) use ($status) {
                                        //
                                        $statusArr = explode(',',$status);
                                        $query->whereIn('gShop.status',$statusArr);
                                    })
                                    ->when(isset($inShopStaffCount) && $inShopStaffCount !== '', function ($query) use ($inShopStaffCount) {
                                        /** @var Builder  $query */
                                        $query->where(function ($_query) use ($inShopStaffCount){
                                            $inShopStaffCountArr = explode(',',$inShopStaffCount);
                                            $_query->whereIn('inShopStaffCount',$inShopStaffCountArr);
                                            if (in_array(6,$inShopStaffCountArr)){
                                                $_query->orWhere('inShopStaffCount','>=',6);
                                            }
                                        });
                                    })
                                    ->when($recordStatus, function ($query) use ($recordStatus) {
                                        /** @var Builder  $query */
                                        $query->where(function ($_query) use ($recordStatus){
                                            foreach (explode(',',$recordStatus) as $_recordStatus){
                                                switch ($_recordStatus) {
                                                    case ShopRecordsEnum::RECORD_STATUS_PENDING:
                                                        $_query->orWhere('pendingCount', '>', 0);
                                                        break;
                                                    case ShopRecordsEnum::RECORD_STATUS_REJECT:
                                                        $_query->orWhere('rejectCount', '>', 0);
                                                        break;
                                                    case ShopRecordsEnum::RECORD_STATUS_CARD_ABNORMAL:
                                                        $_query->orWhere('cardAbnormalCount', '>', 0);
                                                        break;
                                                    case ShopRecordsEnum::RECORD_STATUS_PASS:
                                                        $_query->orWhere([
                                                            ['pendingCount', '=', 0,],
                                                            ['rejectCount', '=', 0,],
                                                            ['cardAbnormalCount', '=', 0,],
                                                        ]);
                                                        break;
                                                }
                                            }
                                        });

                                    })
                                    ->when($councilorId, function ($query) use ($councilorId) {
                                        $query->where('shop.councilorId', $councilorId);
                                    })
                                    ->when($orderBy, function ($query) use ($orderBy) {
                                        if ($orderBy['lastManagerUpdateTime'] ?? []) {
                                            $query->orderBy('lastManagerUpdateTime', $orderBy['lastManagerUpdateTime']);
                                        }
                                        if ($orderBy['lastAuditTime'] ?? []) {
                                            $query->orderBy('lastAuditTime', $orderBy['lastAuditTime']);
                                        }
                                    })
            ->select([
                (new ShopRecordsModel())->getTable().'.*','shop.*',
                'gShop.status as gStatus'
            ]);

        if ($export){
            $paginate = $query->get();
            $list = $paginate;
        } else {
            $paginate = $query->paginate($pageSize, $fields, $pageName = 'page', $pageNum);
            $list = collect($paginate->items());
        }

        $userIds = $list->pluck('councilorId')->unique()->toArray();

        $users = User::query()->whereIn('id', $userIds)->get()->keyBy('id');

        return [
            'pageSize' => $paginate instanceof Paginator ? $paginate->perPage() : null,
            'pageNum'  => $paginate instanceof Paginator ? $paginate->currentPage() : null,
            'count'    => $paginate instanceof Paginator ? $paginate->total() : null,
            'lists'    => $list->map(function ($item) use ($users, $formatDistrictList, $export) {
                $councilor    = $users[$item->councilorId] ?? null;
                $addressPrefixArr = [];
                if ($item->addressPrefix) {
                    $addressPrefixArr = explode('-', $item->addressPrefix);
                }


                return [
                    'id'                    => $item->id,
                    'shopId'                => $item->shopId,
                    'shopCode'              => $item->shopCode,
                    'name'                  => $item->name,
                    'shopStatus'            => $item->gStatus ?: '',
                    'area'                  => $item->addressPrefix,
                    'councilorName'         => $councilor ? $councilor->username : '',
                    'staffCount'            => $item->staffCount,
                    'inShopStaffCount'      => $item->inShopStaffCount,
                    'cardAbnormalCount'     => $item->cardAbnormalCount,
                    'approvedCount'         => $item->approvedCount,
                    'rejectCount'           => $item->rejectCount,
                    'pendingCount'          => $item->pendingCount,
                    'warZone'               => $formatDistrictList[$item->province]['warZone'] ?? '',
                    'provinceName'          => $addressPrefixArr[0] ?? '',
                    'cityName'              => $addressPrefixArr[1] ?? '',
                    'districtName'          => $addressPrefixArr[2] ?? '',
                    'lastManagerUpdateTime' => $item->lastManagerUpdateTime
                        ? date('Y-m-d H:i:s', $item->lastManagerUpdateTime)
                        : '',
                    'lastAuditTime'         => $item->lastAuditTime
                        ? date('Y-m-d H:i:s', $item->lastAuditTime)
                        : '',
                    'expireCount'           => $item->aboutToExpireCount,
                ];
            })->toArray()
        ];

    }


    /**
     * 获得战区列表
     * @param int $provinceCode
     * @return mixed|string
     */
    public static function getWarZoneByProvinceCode(int $provinceCode = 0)
    {
        $provinceRelationWarZone = Cache::remember('provinceRelationWarZone', 3600, function () {
            $list = [];
            $warZoneDistrictList = CommonRemote::getWarZoneDistrictList();
            foreach ($warZoneDistrictList as $item) {
                foreach ($item['provinceList'] as $province) {
                    $list[$province['provinceCode']] = $item['name'];
                }
            }
            return $list;
        });

        if ($provinceCode) {
            return $provinceRelationWarZone[$provinceCode] ?? '';
        } else {
            return $provinceRelationWarZone;
        }
    }

    /**
     * 更新门店日活数据
     * @param $activityDays
     * @return void
     */
    public static function updateShopActivity($activityDays)
    {
        // 先重置
        ShopRecordsModel::query()
            ->update([
                'activityDays' => 0
            ]);

        // 更新门店日活数据
        $shopCodes     = GyDailyDeliveryReportCHModel::getActivityShopLists($activityDays);
        $shopCodeChunk = array_chunk($shopCodes, 500);
        foreach ($shopCodeChunk as $shopCodesItem) {
            ShopRecordsModel::query()
                ->whereIn('shopCode', $shopCodesItem)
                ->update([
                    'activityDays' => $activityDays
                ]);
        }
    }

}
